package com.yida.system.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.yida.common.core.constant.CacheConstants;
import com.yida.common.core.exception.ServiceException;
import com.yida.common.core.utils.DateUtils;
import com.yida.common.core.utils.StringUtils;
import com.yida.common.redis.service.RedisService;
import com.yida.system.api.domain.SysArea;
import com.yida.system.domain.SysUserArea;
import com.yida.system.domain.vo.TreeSelect;
import com.yida.system.mapper.SysAreaMapper;
import com.yida.system.mapper.SysUserAreaMapper;
import com.yida.system.service.ISysAreaService;

/**
 * 系统地区Service业务层处理
 * 
 * @author hmh
 * @date 2022-11-08
 */
@Service
public class SysAreaServiceImpl implements ISysAreaService {

    // 地区列表
    public static final String AREA_LIST = "area.list";

    // 地区树
    public static final String AREA_TREE = "area.tree";

    // 地区key
    public static final String AREA = "area";

    // 街道
    public static final String STREET = "street";

    @Autowired
    private SysAreaMapper sysAreaMapper;

    @Autowired
    private SysUserAreaMapper sysUserAreaMapper;

    @Autowired
    private RedisService redisService;

    /**
     * 项目启动时，初始化参数到缓存
     */
    @PostConstruct
    public void init() {

        loadingAreaCache();
    }

    /**
     * 查询系统地区
     *
     * @param areaId 系统地区主键
     * @return 系统地区
     */
    @Override
    public SysArea selectSysAreaByAreaId(Long areaId) {
        return sysAreaMapper.selectSysAreaByAreaId(areaId);
    }

    /**
     * 查询系统地区列表
     *
     * @param sysArea 系统地区
     * @return 系统地区
     */
    @Override
    public List<SysArea> selectSysAreaList(SysArea sysArea) {
        return sysAreaMapper.selectSysAreaList(sysArea);
    }

    /**
     * 新增系统地区
     *
     * @param sysArea 系统地区
     * @return 结果
     */
    @Override
    public int insertSysArea(SysArea sysArea) {
        sysArea.setCreateTime(DateUtils.getNowDate());
        return sysAreaMapper.insertSysArea(sysArea);
    }

    /**
     * 修改系统地区
     *
     * @param sysArea 系统地区
     * @return 结果
     */
    @Override
    public int updateSysArea(SysArea sysArea) {
        sysArea.setUpdateTime(DateUtils.getNowDate());
        return sysAreaMapper.updateSysArea(sysArea);
    }

    /**
     * 判断当前地区名称是否重复
     *
     * @param sysArea
     * @return
     */
    @Override
    public boolean checkAreaName(SysArea sysArea) {
        SysArea rSysArea = sysAreaMapper.selectSysAreaByAreaName(sysArea.getAreaName());
        if (rSysArea != null) {
            if (rSysArea.getAreaId() != sysArea.getAreaId() && rSysArea.getAreaName() == sysArea.getAreaName()) {
                return true;
            }
        }
        return false;
    }

    @Override
    public void checkAreaAllowed(SysArea sysArea) {
        checkAreaAllowed(sysArea.getAreaId());
    }

    /**
     * 20221206 hmh
     */
    @Override
    public void checkAreaAllowed(Long areaId) {
        if (StringUtils.isNotNull(areaId) && areaId == 1) {
            throw new ServiceException("该地区不允许操作");
        }
    }

    /**
     * 批量删除系统地区
     *
     * @param areaIds 需要删除的系统地区主键
     * @return 结果
     */
    @Override
    public int deleteSysAreaByAreaIds(Long[] areaIds) {
        return sysAreaMapper.deleteSysAreaByAreaIds(areaIds);
    }

    /**
     * 删除系统地区信息
     *
     * @param areaId 系统地区主键
     * @return 结果
     */
    @Override
    public int deleteSysAreaByAreaId(Long areaId) {
        return sysAreaMapper.deleteSysAreaByAreaId(areaId);
    }

    /**
     * 加载参数缓存数据
     */
    @Override
    public void loadingAreaCache() {
        // List<SysArea> sysAreaList = sysAreaMapper.selectSysAreaList(new SysArea());
        List<SysArea> sysAreaList = sysAreaMapper.selectSysAreaAll();
        if (sysAreaList != null && sysAreaList.size() > 0) {
            // List<SysArea> areaTreelist = getChildPerms(cacheSysAreaList,1);
            // 填充地区列表
            redisService.setCacheObject(getCacheKey(AREA_LIST), sysAreaList);
            // 获取区域下的数据
            List<SysArea> areas = setSysAreaCacheByAreaType(sysAreaList, 2);
            redisService.setCacheObject(getCacheKey(AREA), areas);
            List<SysArea> streets = setSysAreaCacheByAreaType(sysAreaList, 3);
            redisService.setCacheObject(getCacheKey(STREET), streets);
            // 填充地区树
            List<TreeSelect> areaTree = selectAreaTreeByAreaId(0L, sysAreaList);
            redisService.setCacheObject(getCacheKey(AREA_TREE), areaTree);
        }
    }

    /**
     * 设置cache key
     *
     * @param configKey 参数键
     * @param type 类型
     * @return 缓存键key
     */
    private String getCacheKey(String configKey) {
        return CacheConstants.CAPTCHA_SYS_AREA + configKey;
    }

    @Override
    public List<TreeSelect> selectAreaTreeByAreaId(Long areaId) {
        return selectAreaTreeByAreaId(areaId, null);
    }

    @Override
    public List<TreeSelect> selectAreaTreeByAreaId(Long areaId, List<SysArea> sysAreaList) {
        if (sysAreaList == null) {
            sysAreaList = redisService.getCacheObject(getCacheKey(AREA_LIST));
        }
        if (sysAreaList != null) {
            if (areaId == null) {
                areaId = 0L;
            }
            List<SysArea> returnSysAreaList = getChildPerms(sysAreaList, areaId);
            return returnSysAreaList.stream().map(TreeSelect::new).collect(Collectors.toList());
        }
        return null;
    }

    @Override
    public Map<String, Object> getAreaStreetInfoByAreaId(String areaIds) {
        Map<String, Object> rs = new HashMap<String, Object>();
        // 获取缓存数据
        List<SysArea> areaList = redisService.getCacheObject(getCacheKey(AREA_LIST));
        List<SysArea> areas = getList(areaIds, areaList, 2);
        List<SysArea> street = getList(areaIds, areaList, 3);
        Map<Long, List<SysArea>> streetDataMap = street.stream().collect(Collectors.groupingBy(SysArea::getParentId));
        rs.put(AREA, areas);
        rs.put(STREET, streetDataMap);
        return rs;
    }

    @Override
    public List<TreeSelect> getAreaTreeInfoByAreaIds(String areaIds) {
        // 获取缓存数据
        List<SysArea> areaList = redisService.getCacheObject(getCacheKey(AREA_LIST));
        if ("1".equals(areaIds)) {
            // 地区1查全部地区进行返回
            return selectAreaInfoByAreaType(2);
        }
        List<SysArea> areas = getList(areaIds, areaList, 2);
        return buildAreaTree(areas).stream().map(TreeSelect::new).collect(Collectors.toList());
    }

    @Override
    public List<SysArea> getAreaByAreaIds(String areaIds) {
        // 获取缓存数据
        List<SysArea> areaList = redisService.getCacheObject(getCacheKey(AREA_LIST));
        if (StringUtils.isEmpty(areaIds)) {
            areaIds = "1";
        }
        // 返回对于地区数据
        return getList(areaIds, areaList, 2);
    }

    /**
     * 根据地区编号获取对应数据
     *
     * @param areaIds
     * @param cacheAreaList
     * @return
     */
    private List<SysArea> getList(String areaIds, List<SysArea> cacheAreaList, int type) {
        String[] areaIdArry = areaIds.split(",");
        List<SysArea> rAreaList = new ArrayList<SysArea>();
        for (SysArea sa : cacheAreaList) {
            if (2 == type) {// 获取区
                if (StringUtils.inStringIgnoreCase(sa.getAreaId().toString(), areaIdArry)) {
                    rAreaList.add(sa);
                }
            } else if (3 == type) {// 获取街道
                if (StringUtils.inStringIgnoreCase(sa.getParentId().toString(), areaIdArry)) {
                    rAreaList.add(sa);
                }
            }
        }
        return rAreaList;
    }

    @Override
    public List<TreeSelect> selectAreaInfoByAreaType(int type) {
        // 0=省,1=市,2=区,3=街道
        List<SysArea> sysAreaList = redisService.getCacheObject(getCacheKey(AREA_LIST));
        // 获取对应区域数据
        List<SysArea> areaList = setSysAreaCacheByAreaType(sysAreaList, type);
        SysArea sysAreaQz = sysAreaList.stream().filter(sa -> sa.getAreaId() == 1L).collect(Collectors.toList()).get(0);
        areaList.add(sysAreaQz);
        return buildAreaTree(areaList).stream().map(TreeSelect::new).collect(Collectors.toList());
    }

    private List<SysArea> setSysAreaCacheByAreaType(List<SysArea> list, int type) {
        List<SysArea> returnList = new ArrayList<SysArea>();
        for (SysArea s : list) {
            if (s.getAreaType() == type) {
                returnList.add(s);
            }
        }
        return returnList;
    }

    /**
     * 构建前端所需要树结构
     *
     * @param menus 菜单列表
     * @return 树结构列表
     */
    // @Override
    public List<SysArea> buildAreaTree(List<SysArea> areas) {
        List<SysArea> returnList = new ArrayList<SysArea>();
        List<Long> tempList = new ArrayList<Long>();
        for (SysArea area : areas) {
            tempList.add(area.getAreaId());
        }
        for (SysArea area : areas) {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(area.getParentId())) {
                recursionFn(areas, area);
                returnList.add(area);
            }
        }
        if (returnList.isEmpty()) {
            returnList = areas;
        }
        return returnList;
    }

    /**
     * 递归列表
     *
     * @param list
     * @param t
     */
    private void recursionFn(List<SysArea> list, SysArea t) {
        // 得到子节点列表
        List<SysArea> childList = getChildList(list, t);
        t.setChildren(childList);
        for (SysArea tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<SysArea> getChildList(List<SysArea> list, SysArea t) {
        List<SysArea> tlist = new ArrayList<SysArea>();
        Iterator<SysArea> it = list.iterator();
        while (it.hasNext()) {
            SysArea n = (SysArea)it.next();
            if (n.getParentId().longValue() == t.getAreaId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<SysArea> list, SysArea t) {
        return getChildList(list, t).size() > 0;
    }

    /**
     * 根据父节点的ID获取所有子节点
     *
     * @param list 分类表
     * @param parentId 传入的父节点ID
     * @return String
     */
    public List<SysArea> getChildPerms(List<SysArea> list, Long parentId) {
        List<SysArea> returnList = new ArrayList<SysArea>();
        for (Iterator<SysArea> iterator = list.iterator(); iterator.hasNext();) {
            SysArea t = (SysArea)iterator.next();
            // 一、根据传入的某个父节点ID,遍历该父节点的所有子节点
            if (t.getParentId() == parentId) {
                recursionFn(list, t);
                returnList.add(t);
            }
        }
        return returnList;
    }

    // @Override
    // public List<TreeSelect> selectAreaTreeByAreaIdArry(Long[] areaIds) {
    // Map<Long,Long> map = new HashMap<Long,Long>();
    // for(Long areaId : areaIds) {
    // map.put(areaId, areaId);
    // }
    // // 获取缓存数据
    // List<SysArea> sysAreaList = redisService.getCacheObject(getCacheKey(AREA_LIST));
    // //存储器
    // List<SysArea> rSysAreaList = new ArrayList<SysArea>();
    // for(SysArea sysArea : sysAreaList) {
    // Long areaId = sysArea.getAreaId();
    // Long parentId = sysArea.getParentId();
    // //默认保留泉州用于显示
    // if(areaId==1) {
    // rSysAreaList.add(sysArea);
    // }
    //// System.out.println("areaId:"+sysArea.getAreaId());
    //// System.out.println("areaName:"+sysArea.getAreaName());
    //// System.out.println("areaIdParentId:"+sysArea.getParentId());
    //// System.out.println("areaIdMP:"+map.get(parentId));
    //// if(map.get(areaId)!=null && areaId!=1 && map.get(parentId)==parentId || map.get(0l)!=null) {
    //// rSysAreaList.add(sysArea);
    //// }
    // if((areaId!=1 && map.get(parentId)==parentId) || map.get(0l)!=null) {
    // rSysAreaList.add(sysArea);
    // }
    //
    // }
    // return buildAreaTree(rSysAreaList).stream().map(TreeSelect::new).collect(Collectors.toList());
    // }

    @Override
    public List<TreeSelect> selectAreaTreeByAreaIdArry(Long[] areaIds) {
        // 获取缓存数据
        List<SysArea> sysAreaList = redisService.getCacheObject(getCacheKey(AREA_LIST));
        // 存储器
        List<SysArea> rSysAreaList = new ArrayList<SysArea>();
        SysArea sysAreaQz = sysAreaList.stream().filter(sa -> sa.getAreaId() == 1L).collect(Collectors.toList()).get(0);
        rSysAreaList.add(sysAreaQz);
        for (Long areaId : areaIds) {
            if (areaId == 0 || areaId == 1) {
                rSysAreaList.clear();
                // rSysAreaList = new ArrayList<SysArea>();
                rSysAreaList.addAll(sysAreaList);
                break;
            }
            SysArea sysArea = null;
            if (sysAreaList.stream().anyMatch(sa -> sa.getAreaId() == areaId)) {
                // 获取对应地区数据
                sysArea = sysAreaList.stream().filter(sa -> sa.getAreaId() == areaId).collect(Collectors.toList()).get(0);
            }
            // 数据空或者类型为街道跳过
            if (sysArea == null || sysArea.getAreaType() == 3) {
                continue;
            }
            // 获取对应地区数据子节点
            List<SysArea> clildList = getChildList(sysAreaList, sysArea);
            if (clildList != null && clildList.size() > 0) {
                sysArea.setChildren(clildList);
            }
            rSysAreaList.add(sysArea);
        }
        return buildAreaTree(rSysAreaList).stream().map(TreeSelect::new).collect(Collectors.toList());
    }

    @Override
    public int insertUserAreas(Long areaId, Long[] userIds) {
        // 新增用户与地区管理
        List<SysUserArea> list = new ArrayList<SysUserArea>();
        for (Long userId : userIds) {
            SysUserArea ua = new SysUserArea();
            ua.setUserId(userId);
            ua.setAreaId(areaId);
            list.add(ua);
        }
        return sysUserAreaMapper.batchUserArea(list);
    }

    @Override
    public List<SysArea> selectSysAreaByUserId(Long userId) {
        return sysAreaMapper.selectSysAreaByUserId(userId);
    }

    @Override
    public String selectSysAreaToStringByUserId(Long userId) {
        StringBuffer sb = new StringBuffer();
        // 管理员拥有所有权限
        if (userId == 1) {
            sb.append("0");
        } else {
            // 获取地区集合
            List<SysArea> areaList = selectSysAreaByUserId(userId);
            if (areaList != null && areaList.size() > 0) {
                areaList.stream().forEach(sa -> {
                    sb.append(sa.getAreaId()).append(",");
                });
            }
            if (sb.length() > 0) {
                // 删除末位的","
                sb.deleteCharAt(sb.length() - 1);
            }
        }
        return sb.toString();
    }

    @Override
    public int deleteBindUser(SysUserArea sysUserArea) {
        return sysUserAreaMapper.deleteUserAreaInfo(sysUserArea);
    }

    @Override
    public int deleteBindUsers(Long areaId, Long[] userIds) {
        return sysUserAreaMapper.deleteUserAreaInfos(areaId, userIds);
    }

}
